package array;

public class Array {

    private Object[] m_arrData;
    //当前数组的数据量
    private int m_iCount;

    public Array() {
        this(10);
    }

    public Array(int iCapacity) {
        m_arrData = new Object[iCapacity];
        m_iCount = 0;
    }

    public int getCount() {
        return this.m_iCount;
    }

    public boolean isEmpty() {
        return this.m_iCount == 0;
    }

    public void addToHead(Object objData) throws IllegalAccessException {
        this.addByIndex(0, objData);
    }

    public void addToLast(Object objData) throws IllegalAccessException {
        this.addByIndex(this.m_iCount, objData);
    }

    public void addByIndex(int iIndex, Object object) throws IllegalAccessException {
        checkIndexForAdd(iIndex);

        //当前数组满了，需要扩容
        if (this.m_iCount == this.m_arrData.length) {
            this.reSize(2 * this.m_arrData.length);
        }

        //将插入点之后的数据都向后移动一位
        for (int i = this.m_iCount - 1; i >= iIndex; i--) {
            this.m_arrData[i + 1] = this.m_arrData[i];
        }

        this.m_arrData[iIndex] = object;
        this.m_iCount++;
    }

    public Object deleteFirst() throws IllegalAccessException {
        return this.deleteByIndex(0);
    }


    public Object deleteLast() throws IllegalAccessException {

        return deleteByIndex(this.m_iCount - 1);
    }

    public Object deleteByIndex(int iIndex) throws IllegalAccessException {
        checkIndexForDelete(iIndex);

        Object objTemp = this.m_arrData[iIndex];
        for (int i = iIndex; i < this.m_iCount; i++) {
            this.m_arrData[i] = this.m_arrData[i + 1];
        }

        this.m_iCount--;
        this.m_arrData[this.m_iCount] = null;

        if (this.m_iCount == this.m_arrData.length / 4 && this.m_arrData.length / 2 != 0) {
            this.reSize(this.m_arrData.length / 2);
        }

        return objTemp;
    }

    public Object getByIndex(int iIndex) throws IllegalAccessException {
        checkIndexForDelete(iIndex);

        return m_arrData[iIndex];
    }

    public int find(Object objData) {
        for (int i = 0; i < m_iCount; i++) {
            if (m_arrData[i] == objData) {
                return i;
            }
        }

        return -1;
    }

    public boolean contain(Object objData) {
        for (int i = 0; i < m_iCount; i++) {
            if (m_arrData[i] == objData) {
                return true;
            }
        }

        return false;
    }

    public int getSize() {
        return this.m_arrData.length;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < this.m_iCount; i++) {
            sb.append(this.m_arrData[i] + ", ");
        }
        return sb.toString();
    }

    //重置数组大小，时间复杂度为 O(n)
    private void reSize(int iCapacity) {
        Object[] arrData = new Object[iCapacity];

        for (int i = 0; i < this.m_iCount; i++) {
            arrData[i] = this.m_arrData[i];
        }

        this.m_arrData = arrData;
    }

    //数组之间不允许留空,
    private void checkIndexForAdd(int iIndex) throws IllegalAccessException {
        if (iIndex < 0 || iIndex > this.m_iCount) {
            throw new IllegalAccessException("下标不合规");
        }
    }

    //只允许删除已经存在数据的下标
    private void checkIndexForDelete(int iIndex) throws IllegalAccessException {
        if (iIndex < 0 || iIndex >= this.m_iCount) {
            throw new IllegalAccessException("下标不合规");
        }
    }
}
